class AsteroidWithTax: public AsteroidWithSize
{
public:
  unsigned char hasTax;
  char taxClasses[31];
  //  Bus-Bus-SMA-Tho-Add-Dem-Ca-Ga - 
  //  Dem-   -SS -len-it -Car-rv-ia -  
  //  0123456789012345678901234567890
  //  0         1         2         3
  /*
  char taxDeMeoCarry[7];
  char taxCarvano[7];
  char taxSpectro[7];
  */
  
  float astar;
  float sigmaAstar;
  float i_z;
  float sigmai_z;

  float slope;
  float sigmaSlope;
  float color;
  float sigmaColor;

  float Fo; // Olivine abundnace i.e. [ol/(ol+low-Ca px)] %
  
  AsteroidWithTax():AsteroidWithSize()
  {
    memset(taxClasses,'-',31);  taxClasses[30]=0;
    astar=sigmaAstar=i_z=sigmai_z=slope=sigmaSlope=color=hasTax=sigmaColor=Fo=0;
  };

  void reset()
  {
    AsteroidWithSize::reset();
    memset(taxClasses,'-',31);  taxClasses[30]=0;
    astar=sigmaAstar=i_z=sigmai_z=slope=sigmaSlope=color=hasTax=sigmaColor=Fo=0;
  }

   void printOscElem()
  {
    // OSCULATING ELEM
    printf("%06ld %20s %7s %5.2f %4.2f %7.4lf %7.4lf %7.4lf %8.3f %7.3f %5.3f %5.3f %6.2f %01d %30s\
 %06ld %02x %01d %02d %2d %2d %2d %2d %4.2f %4.2f\n",
    	   Number, Designation, pack, H, G, a, e, sini,
    	   D, sigmaD, pV, sigmapV, rotationPeriod, hasWiseObs, taxClasses, familyDavidN,
	   refs[3], hasTax, (int)Fo, nW1,nW2,nW3,nW4, astar, i_z);
  };

   void printOscElemNEAsource()
  {
    // OSCULATING ELEM
    printf("%06ld %20s %7s %5.2f %4.2f %7.4lf %7.4lf %7.4lf %8.3f %7.3f %5.3f %5.3f %6.2f %01d \
 %06ld %02x %01d %02d %2d %2d %2d %2d ",
    	   Number, Designation, pack, H, G, a, e, sini,
    	   D, sigmaD, pV, sigmapV, rotationPeriod, hasWiseObs, familyDavidN,
	   refs[3], hasTax, (int)Fo, nW1,nW2,nW3,nW4);
        for (int i=0; i<=6; i++)
      printf("%5.2f ", neaSourceRegion[i]);
    printf("\n");

  };

  void print()
  {
     // PROPER ELEM
    printf("%06ld %20s %7s %5.2f %4.2f %7.4lf %7.4lf %7.4lf %8.3f %7.3f %5.3f %5.3f %6.2f %01d %30s\
 %06ld %02x %01d %02d %2d %2d %2d %2d %5.2f %5.2f\n",
    	   Number, Designation, pack, H, G, ap, ep, sinip,
    	   D, sigmaD, pV, sigmapV, rotationPeriod, hasWiseObs, taxClasses, familyDavidN,
	   refs[3], hasTax, (int)Fo, nW1,nW2,nW3,nW4,astar, i_z);
    
    //    printf("%06ld %20s %10s %5.2lf %5.2lf %7.4lf %7.4lf %7.4lf %7.4lf %7.4lf %7.4lf %8.3lf %7.3lf %5.3lf %5.3lf %6.2lf %01d %5s %1s %2s %05ld\n",
    //   	   Number, Designation, pack, H, G, a, e, sini, ap, ep, sinip,
    //    	   D, sigmaD, pV, sigmapV, rotationPeriod, hasWiseObs, taxSpectro, taxDeMeoCarry, taxCarvano, familyDavidN);
    //printf("%06ld %20s %10s %5.2lf %5.2lf %7.4lf %7.4lf %7.4lf %7.4lf %7.4lf %7.4lf %8.3lf %7.3lf %5.3lf %5.3lf %6.2lf %01d %5s %05ld\n",
	// Number, Designation, pack, H, G, a, e, sini, ap, ep, sinip,
	//   D, sigmaD, pV, sigmapV, rotationPeriod, hasWiseObs, taxSpectro, familyDavidN);

    // printf("%ld %20s %lf %lf %lf %lf %lf %lf %lf\n", Number, Designation, H, G, pa, pe, psini, D, pV);
  };

  void DeMeoCarry13String2Asteroid(string line)
  {
    reset();
    Number=atol(&line.at(0));
        // remove spaces while copying designation string
    char *write = Designation;
    char *read = &line.at(7);
    int j=0;
    do {
      if ((*read != ' ') && (*read != '_'))
	*write++ = *read;
    } while ((*read++) && ((++j)<16));
    *write++ =0;
    Designation[16]=0;

    taxClasses[20]=line.at(23);
    hasTax=1;

    designation2pack();
    if (Number>0) number2pack();
  };
  
  void Carvano10String2Asteroid(string line)
  {
    reset();
    Number=atol(&line.at(0));
        // remove spaces while copying designation string
    char *write = Designation;
    char *read = &line.at(24);
    int j=0;
    do {
      if ((*read != ' ') && (*read != '_'))
	*write++ = *read;
    } while ((*read++) && ((++j)<12));
    *write++ =0;
    Designation[12]=0;

    memcpy(&taxClasses[24],&line.at(36),2);
    hasTax=1;

    designation2pack();
    if (Number>0) number2pack();
  };

  void taxonomy10String2Asteroid(string line)
  {
    reset();
    Number=atol(&line.at(0));

    
        // remove spaces while copying designation string
    char *write = Designation;
    char *read = &line.at(26);
    int j=0;
    do {
      if ((*read != ' ') && (*read != '_'))
	*write++ = *read;
    } while ((*read++) && ((++j)<12));
    *write++ =0;
    Designation[12]=0;

    designation2pack();
    if (Number>0) number2pack();

    memcpy(&taxClasses[12],&line.at(37),3); // tholen
    //    memcpy(barucciClass,&line.at(48),2);
    //memcpy(tedescoClass,&line.at(54),3);
    //memcpy(howellClass,&line.at(61),3); // Howell to additional
    memcpy(&taxClasses[8],&line.at(72),3); // SMASS
    memcpy(&taxClasses[4],&line.at(76),3); // BUS
    memcpy(&taxClasses[16],&line.at(88),3); // s3os2Class to additional
    memcpy(&taxClasses[0],&line.at(96),3);  // BUS DE MEO

    hasTax=1;
    /*
    if (busdemeoClass[0]!='-') // we have a good BusDemeo-Class 1
      { memcpy(taxSpectro, busdemeoClass, 7); refs[5]+=BUSDEMEO;}
    else {
      if (smassClass[0]!='-') // we have a good SMASS 2
	{ memcpy(taxSpectro, smassClass, 7); refs[5]+=SMASS2;}
      else {
	if (busClass[0]!='-') // we have a good Bus Class 3
	  { memcpy(taxSpectro, busClass, 7); refs[5]+=BUSBINZEL;}
	else {
	  if (s3os2Class[0]!='-') // we have a good s3os2Class Class 4
	    { memcpy(taxSpectro, s3os2Class, 7); refs[5]+=S3OS2;}
	  else {
	    if (tholenClass[0]!='-') // we have a good tholenClass Class 5
	      { memcpy(taxSpectro, tholenClass, 7); refs[5]+=THOLEN;}
	    else {
	      if (tedescoClass[0]!='-') // we have a good tedescoClass Class 7
		{ memcpy(taxSpectro, tedescoClass, 7); refs[5]+=TEDESCOTAX;}
	      else {
		if (barucciClass[0]!='-') // we have a good barucciClass Class 7
		  { memcpy(taxSpectro, barucciClass, 7); refs[5]+=BARUCCI;}
		else {
		  if (howellClass[0]!='-') // we have a good barucciClass Class 7
		    { memcpy(taxSpectro, howellClass, 7); refs[6]+=HOWELL;}
		}
	      }
	    }
	  }
	}
      }	
    }
    */
  };

  void fixTaxData()
  {
    int taxDataLen=strlen(taxClasses);
    for(int i=0; i<taxDataLen; i++)
      if ((taxClasses[i]<'A') || ((taxClasses[i]>'Z')&&(taxClasses[i]<'a')) || (taxClasses[i]>'z'))
	taxClasses[i]='-';
  };
  

  int hasTheseTaxonomies(vector <string> taxa)
  {
    int len=taxa.size();
    for (int i=0; i<len; i++)
      if (strstr(taxClasses, &taxa[i].at(0))) return 1;

    return 0;
  };

  int hasNotTheseTaxonomies(vector <string> taxa)
  {
    int len=taxa.size();
    for (int i=0; i<len; i++)
      if (strstr(taxClasses, &taxa[i].at(0))) return 0;

    return 1;
  };

  int line2aStarMOC4(string line)
  {
    float i,z,iErr,zErr;

    Number=(long) atol(&line.at(244));
    memcpy(Designation,&line.at(252),10); Designation[10]=0;
    astar=(float)atof(&line.at(218));
    sigmaAstar=(float)atof(&line.at(224));
    i=(float)atof(&line.at(196));
    iErr=(float)atof(&line.at(202));
    z=(float)atof(&line.at(207));
    zErr=(float)atof(&line.at(213));
    i_z=i-z;
    sigmai_z=sqrt(iErr*iErr+zErr*zErr);
    return 1;
  };
};



template<class T>
void readInDeLeon16(T myAst[], long indLastMPC, long indLastNumbMPC, string* ids, long nIds)
{
  ifstream myfile ("deLeonPolalia.dat");
  long ind;
  string line;
  char tax[5];

  if (myfile.is_open())
  {
    while ( getline (myfile,line))
      {
	if (line.length()>1)
	  {
	    sscanf(&line.at(0),"%ld %s", &ind, tax);
	    if (ind>0)
	      {
		strcpy(&myAst[ind-1].taxClasses[16], tax);
		myAst[ind-1].hasTax=1;
		myAst[ind-1].refs[5]+=DELEON16;
	      }
	  }
      }
  }
  myfile.close();
}

template<class T>
void readInPinillaAlonso16(T myAst[], long indLastMPC, long indLastNumbMPC, string* ids, long nIds)
{
  ifstream myfile ("pinillaalonso16.dat");
  long ind;
  string line;
  char tax[5];

  if (myfile.is_open())
  {
    while ( getline (myfile,line))
      {
	if (line.length()>1)
	  {
	    sscanf(&line.at(0),"%ld %s", &ind, tax);
	    if (ind>0)
	      {
		strcpy(&myAst[ind-1].taxClasses[16], tax);
		myAst[ind-1].hasTax=1;
		myAst[ind-1].refs[5]+=PINILLA16;
	      }
	  }
      }
  }
  myfile.close();
}

template<class T>
void readInTaxonomy10(T myAst[], long indLastMPC, long indLastNumbMPC, string* ids, long nIds)
{
  ifstream myfile ("taxonomy10.tab");
  long ind;
  string line;
  char tax[5];
  AsteroidWithTax ast;

  if (myfile.is_open())
  {
    while ( getline (myfile,line))
      {
	if (line.length()>1)
	  {
	    	    // convert linefile to asteroid
	    ast.taxonomy10String2Asteroid(line);
	    if (ast.Number>0)
	      {
		strcpy(myAst[ast.Number-1].taxClasses, ast.taxClasses);
		myAst[ast.Number-1].hasTax=ast.hasTax;
	      }
	  }
      }
    myfile.close();
  } else cout << "file taxonomy10.tab not found " <<endl;
}

template<class T>
void readInFo(T myAst[], long indLastMPC, long indLastNumbMPC, string* ids, long nIds)
{
  ifstream myfile ("astfo.txt");
  string line;
  long number;
  float fo;

  if (myfile.is_open())
  {
    while ( getline (myfile,line))
      {
	if (line.length()>1)
	  {
	    sscanf(&line.at(0), "%ld %f", &number, &fo);
	    //	    cout << line << " " << number << " " << fo << endl;
	    if (number>0)
		myAst[number-1].Fo=fo;
	  }
      }
    myfile.close();
  } else cout << "astfo.txt NOT FOUND " <<endl;

  ifstream myfileNEA ("neafo.txt");
  if (myfileNEA.is_open())
  {
    while ( getline (myfileNEA,line))
      {
	if (line.length()>1)
	  {
	    sscanf(&line.at(0), "%ld %f", &number, &fo);
	    //cout << line << " " << number << " " << fo << endl;
	    if (number>0)
		myAst[number-1].Fo=fo;
	  }
      }
    myfileNEA.close();
  } else cout << "neafo.txt NOT FOUND " <<endl;
}

template<class T>
void readInSDSSmoc4(T myAst[], long indLastMPC, long indLastNumbMPC, string* ids, long nIds)
{
  ifstream myfile ("ADR4.dat");
  string line;
  AsteroidWithTax ast;

  if (myfile.is_open())
  {
    while ( getline (myfile,line))
      {
	if (line.length()>1)
	  {
	    ast.line2aStarMOC4(line);
	    if (ast.Number>0)
	      {
		//		ast.print();
		myAst[ast.Number-1].astar=ast.astar;
		myAst[ast.Number-1].sigmaAstar=ast.sigmaAstar;
		myAst[ast.Number-1].i_z=ast.i_z;
		myAst[ast.Number-1].sigmai_z=ast.sigmai_z;
	      }
	  }
      }
    myfile.close();
  } else cout << "astfo.txt NOT FOUND " <<endl;
}
